package com.tvunetworks.center.device.controller.openapi;

import com.tvunetworks.center.common.model.SearchDeviceParam;
import com.tvunetworks.center.common.model.param.AddAndRemoveRPairParam;
import com.tvunetworks.center.common.model.param.AddAndRemoveSourcePairParam;
import com.tvunetworks.center.common.model.param.PeerIdListParam;
import com.tvunetworks.center.common.model.param.ReceiverDeleteExtParam;
import com.tvunetworks.center.common.model.param.search.SlugInfo;
import com.tvunetworks.center.common.util.*;
import com.tvunetworks.center.device.constant.DeviceApiConstant;
import com.tvunetworks.center.device.model.GridMetadata;
import com.tvunetworks.center.device.model.api.*;
import com.tvunetworks.center.device.model.json.DeviceIpPort;
import com.tvunetworks.center.device.model.json.RidAndSourceId;
import com.tvunetworks.center.device.model.param.AddExtToReceiverParam;
import com.tvunetworks.center.device.model.param.GetChannelParam;
import com.tvunetworks.center.device.model.vo.DeviceApiParam;
import com.tvunetworks.center.device.model.vo.UserDeviceStructure;
import com.tvunetworks.center.device.model.vo.VoDevice;
import com.tvunetworks.center.device.service.*;
import com.tvunetworks.center.device.service.feign.UserFeignService;
import com.tvunetworks.center.device.util.AnywhereAuthUtil;
import com.tvunetworks.center.device.util.HttpRequestUtil;
import com.tvunetworks.center.device.util.IpUtils;
import com.tvunetworks.center.gs.model.Device;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.xml.sax.InputSource;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

/**
 * @program: tvucc-aggregator
 * @description: API
 * @author Kevin_Li
 * @create: 2019-10-09 18:35
 **/
@Slf4j
@Controller
@RequestMapping(value = {"openapi/cc/${openApiVersion}/device", "openapi/${openApiVersion}/device"})
public class DeviceApiController {

    @Autowired
    private DeviceApiService deviceApiService;
    @Autowired
    private ReceiverControlService receiverControlService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private CustomizedCCService customizedCCService;
    @Autowired
    private GridMetadataService gridMetadataService;
    @Autowired
    private DeviceGeoApiService deviceGeoApiService;
    @Autowired
    private UserFeignService userFeignService;
    @Autowired
    private AnywhereAuthUtil anywhereAuthUtil;
    @Autowired
    private ExtService extService;
    @Autowired
    private ExternalReceiverRelationService externalReceiverRelationService;
    /**
     * 获取device的ip
     * @param pids pids
     * @return list
     * @throws ExecutionException 编译异常
     * @throws InterruptedException 编译异常
     */
    @ResponseBody
    @PostMapping("/getDeviceIpPort")
    public Result getDeviceIpPort(@RequestBody List<String> pids) throws ExecutionException, InterruptedException {
        List<DeviceIpPort> list = deviceService.getDeviceIpPort(pids);
        return ResultUtil.success(list);
    }

    /**
     * 添加或者移除R的配对
     * @param param param
     * @return success
     */
    @ResponseBody
    @PostMapping("/addAndRemoveRPair")
    public Result addAndRemoveRPair(@RequestBody AddAndRemoveRPairParam param) {
        log.error("addAndRemoveRPair param:[{}]", param);
        return ResultUtil.success();
    }

    /**
     *
     * @param param param
     * @return  Result
     */
    @ResponseBody
    @PostMapping("/addAndRemoveSourcePair")
    public Result addAndRemoveSourcePair(@RequestBody AddAndRemoveSourcePairParam param) {
        log.error("addAndRemoveRPair param:[{}]", param);
        return ResultUtil.success();
    }

    /**
     *
     * @param param param
     * @param request request
     * @return Result
     */
    @PostMapping("/getChannel")
    @ResponseBody
    public Result getChannel(@RequestBody GetChannelParam param, HttpServletRequest request) {
        String ip = BaseHttpUtil.getBrowerIpAddress(request);
        param.setIp(ip);
        param.setNotCheckAccessApp(true);
        String rid = customizedCCService.getChannel(param);
        return ResultUtil.success(rid);
    }

    /**
     * 获取device信息
     * @param param param
     * @return Result
     */
    @PostMapping(value = "/listDevice")
    @ResponseBody
    public Result listDevice(@RequestBody @Valid PeerIdListParam param) {
        if (param.getPeerIds() == null) {
            return ResultUtil.paramErrorInfo();
        }
        List<Device> devices = deviceService.listCurrentDevice(param.getPeerIds());
        return ResultUtil.success(devices);
    }

    /**
     * 开始直播
     * @param param param
     * @return Result
     */
    @PostMapping(value = "/startLive")
    @ResponseBody
    public Result startLive(@RequestBody RidAndSourceId param) {
        if (StringUtils.isEmpty(param.getRid()) || StringUtils.isEmpty(param.getSourceId())) {
            return ResultUtil.paramErrorInfo();
        }
        Result<String> result = receiverControlService.startLiveForAPI(param.getRid(), param.getSourceId());
        return result;
    }

    /**
     *停止直播
     * @param param param
     * @return Result
     */
    @PostMapping(value = "/stopLive")
    @ResponseBody
    public Result stopLive(@RequestBody RidAndSourceId param) {
        if (StringUtils.isEmpty(param.getRid())) {
            return ResultUtil.paramErrorInfo();
        }
        Result<String> result = receiverControlService.stopLiveForAPI(param.getRid(), param.getSourceId());
        return result;
    }

    /**
     * 根据用户分页获取设备
     * @param param param
     * @return Result
     */
    @PostMapping(value = "/pageDeviceList")
    @ResponseBody
    public Result<Object> pageDeviceList(@RequestBody SearchDeviceParam param) {
        return deviceApiService.pageDevicesByUser(param);
    }

    /**
     * 批量过去device信息
     * @param request request
     * @param response response
     */
    @PostMapping(value = "/getDeviceList")
    public void getDeviceList(HttpServletRequest request, HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        response.setHeader("content-type", "text/html;charset=UTF-8");
        DeviceApiParam deviceApiParam = new DeviceApiParam();
        Result<UserDeviceStructure> result = null;
        try {
            String requestdata = HttpRequestUtil.getRequestDate(request);
            log.error("[Grid API][GetDeviceList][Request data:]" + requestdata);
            //判断参数为xml还是json
            if ("application/xml".equals(request.getContentType())) {
                //xml参数
                try {
                    deviceApiParam = this.analysisXml(requestdata);
                }catch (Exception e){
                    log.error(e.toString(), e);
                    result = ResultUtil.error("81000018", "xml analysis exception");
                    deviceApiParam.setType(DeviceApiConstant.XML_PARAM);
                    return;
                }
                deviceApiParam.setType(DeviceApiConstant.XML_PARAM);
            } else {
                //json参数
                try {
                    deviceApiParam = JsonUtil.toObject(requestdata, DeviceApiParam.class);
                }catch (Exception e){
                    log.error(e.toString(), e);
                    result = ResultUtil.error("81000019", "json analysis exception");
                    deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
                    return;
                }
                //deviceApiParam = deviceApiParam1;
                deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
            }
            deviceApiParam.setIp(BaseHttpUtil.getBrowerIpAddress(request));
            result = deviceApiService.getDeviceListByUser(deviceApiParam);
        } catch (Exception e) {
            deviceApiParam = new DeviceApiParam();
            deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
            result = ResultUtil.exception();
            log.error(e.toString(), e);
        } finally {
            this.response(response, result, deviceApiParam.getType(), "getDeviceList");
        }
    }

    /**
     *
     * @param request request
     * @param response response
     */
    @PostMapping(value = "/getGridMetadata")
    public void getGridMetadata(HttpServletRequest request, HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        response.setHeader("content-type", "text/html;charset=UTF-8");
        DeviceApiParam deviceApiParam = new DeviceApiParam();
        Result<GridMetadata> result = null;
        try {
            String requestdata = HttpRequestUtil.getRequestDate(request);
            log.error("[Grid API][getGridMatedata][Request data:]" + requestdata);
            //判断参数为xml还是json
        //    String accessKey = request.getHeader("AccessKey");
            if ("application/xml".equals(request.getContentType())) {
                //xml参数
                try {
                    deviceApiParam = this.analysisXml(requestdata);
                }catch (Exception e){
                    log.error(e.toString(), e);
                    result = ResultUtil.error("81000018", "xml analysis exception");
                    deviceApiParam.setType(DeviceApiConstant.XML_PARAM);
                    return;
                }
                deviceApiParam.setType(DeviceApiConstant.XML_PARAM);
            } else {
                //json参数
                try {
                     com.alibaba.fastjson.JSONObject requestObject = com.alibaba.fastjson.JSONObject.parseObject(requestdata);
                    String appkey = requestObject.getString("Appkey");
                    String timestamp = requestObject.getString("Timestamp");
                    String signature = requestObject.getString("Signature");
                    String peerId = requestObject.getString("PeerId");
                    deviceApiParam.setAppkey(appkey);
                    deviceApiParam.setTimestamp(timestamp);
                    deviceApiParam.setSignature(signature);
                    deviceApiParam.setPeerId(peerId);
                }catch (Exception e){
                    log.error(e.toString(), e);
                    result = ResultUtil.error("81000019", "json analysis exception");
                    deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
                    return;
                }
                deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
            }
            deviceApiParam.setIp(BaseHttpUtil.getBrowerIpAddress(request));
            result = deviceApiService.getGridMetadata(deviceApiParam);
            log.error("[Grid API][getGridMatedata][result data:]" + result);
        } catch (Exception e) {
            result = ResultUtil.exception();
            deviceApiParam = new DeviceApiParam();
            deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
            log.error(e.toString(), e);
        } finally {
            this.responseGridMetadata(response, result, deviceApiParam.getType());
        }
    }

    /**
     *
     * @param request request
     * @param response response
     */
    @PostMapping(value = "/updateGridMetadata")
    public void updateGridMetadata(HttpServletRequest request, HttpServletResponse response) {
        DeviceApiParam deviceApiParam = new DeviceApiParam();
        Result<GridMetadata> result = new Result<>();
        GridMetadata gridMetadata = null;
        try {
            String requestdata = HttpRequestUtil.getRequestDate(request);
            log.error("[Grid API][updateGridMetadata][Request data:]" + requestdata);
            Result<DeviceApiParam> analysisResult ;
            //判断参数为xml还是json
            if ("application/xml".equals(request.getContentType())) {
                //xml参数
                analysisResult = this.analysisUpdateGridMetadataXml(requestdata);
            } else {
                //json参数
                try {
                    analysisResult = this.analysisUpdateGridMetadataJson(requestdata);
                }catch (Exception e){
                    log.error(e.toString(), e);
                    result = ResultUtil.error("81000019", "json analysis exception");
                    deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
                    return;
                }
            }
            GridMetadata gridMetadata1 = analysisResult.getResult().getGridMetadata();
            if (gridMetadata1 == null) {
                result.setErrorCode(analysisResult.getErrorCode());
                result.setErrorInfo(analysisResult.getErrorInfo());
                deviceApiParam = analysisResult.getResult();
                return;
            }
            deviceApiParam = analysisResult.getResult();
            deviceApiParam.setIp(BaseHttpUtil.getBrowerIpAddress(request));
            result = deviceApiService.updateGridMetadata(deviceApiParam);
            log.error("[Grid API][updateGridMetadata][result data:]" + result);
        } catch (Exception e) {
            result = ResultUtil.exception();
            deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
            log.error(e.toString(), e);
        } finally {
            this.responseGridMetadata(response, result, deviceApiParam.getType());
        }
    }

    /**
     *
     * @param request  request
     * @param response response
     */
    @PostMapping(value = "/getStatus")
    public void getStatus(HttpServletRequest request, HttpServletResponse response) {
        DeviceApiParam deviceApiParam = new DeviceApiParam();
        Result<UserDeviceStructure> result = null;
        try {
            String requestdata = HttpRequestUtil.getRequestDate(request);
            log.error("[Grid API][getStatus][Request data:]" + requestdata);
            //判断参数为xml还是json
            if ("application/xml".equals(request.getContentType())) {
                //xml参数
                try {
                deviceApiParam = this.analysisGetStatusXml(requestdata);
                }catch (Exception e){
                    log.error(e.toString(), e);
                    result = ResultUtil.error("81000018", "xml analysis exception");
                    deviceApiParam.setType(DeviceApiConstant.XML_PARAM);
                    return;
                }
                deviceApiParam.setType(DeviceApiConstant.XML_PARAM);
            } else {
                //json参数
                try {
                    deviceApiParam = JsonUtil.toObject(requestdata, DeviceApiParam.class);
                }catch (Exception e){
                    log.error(e.toString(), e);
                    result = ResultUtil.error("81000019", "json analysis exception");
                    deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
                    return;
                }
                //deviceApiParam = deviceApiParam1;
                deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
            }
            deviceApiParam.setIp(BaseHttpUtil.getBrowerIpAddress(request));
            result = deviceApiService.getStatus(deviceApiParam);
        } catch (Exception e) {
            deviceApiParam = new DeviceApiParam();
            deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
            result = ResultUtil.exception();
            log.error(e.toString(), e);
        } finally {
            this.response(response, result, deviceApiParam.getType(), "getStatus");
        }
    }

    /**
     * 删除ext
     * @param request request
     * @param response response
     */
    @PostMapping(value = "/deleteExt")
    public void deleteExt(HttpServletRequest request, HttpServletResponse response) {
        DeviceApiParam deviceApiParam = new DeviceApiParam();
        Result<UserDeviceStructure> result = null;
        try {
            String requestdata = HttpRequestUtil.getRequestDate(request);
            log.error("[Grid API][deleteExt][Request data:]" + requestdata);
            //判断参数为xml还是json
            if ("application/xml".equals(request.getContentType())) {
                //xml参数
                try {
                    deviceApiParam = this.analysisXml(requestdata);
                }catch (Exception e){
                    log.error(e.toString(), e);
                    result = ResultUtil.error("81000018", "xml analysis exception");
                    deviceApiParam.setType(DeviceApiConstant.XML_PARAM);
                    return;
                }
                deviceApiParam.setType(DeviceApiConstant.XML_PARAM);
            } else {
                //json参数
                try {
                    deviceApiParam = JsonUtil.toObject(requestdata, DeviceApiParam.class);
                }catch (Exception e){
                    log.error(e.toString(), e);
                    result = ResultUtil.error("81000019", "json analysis exception");
                    deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
                    return;
                }
                //deviceApiParam = deviceApiParam1;
                deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
            }
            deviceApiParam.setIp(BaseHttpUtil.getBrowerIpAddress(request));
            result = deviceApiService.deleteExt(deviceApiParam);
        } catch (Exception e) {
            deviceApiParam = new DeviceApiParam();
            deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
            result = ResultUtil.exception();
            log.error(e.toString(), e);
        } finally {
            this.response(response, result, deviceApiParam.getType(), "deleteExt");
        }
    }


    private DeviceApiParam analysisGetStatusXml(String requestdata) throws Exception {
        //解析xml
        DeviceApiParam deviceApiParam = new DeviceApiParam();
        if (requestdata != null && requestdata.length() > 0) {
            Element data = null;
            StringReader sr = new StringReader(requestdata);
            InputSource is = new InputSource(sr);
            SAXReader reader = new SAXReader();
            org.dom4j.Document document = reader.read(is);
            //get root Node
            Element root = document.getRootElement();
            if (root.content().size() != 0) {
                deviceApiParam = analysisXmlAuthData(deviceApiParam, root);
                data = root.element("Data");
                if (data != null ) {
                    if (data.element("PeerIds") != null) {
                        String peerIds = data.element("PeerIds").getStringValue();
                        if (peerIds != null) {
                            deviceApiParam.setPeerIds(peerIds);
                        }
                    }
                }
            }
        }
        return deviceApiParam;
    }

    private DeviceApiParam analysisXml(String requestdata) throws Exception {
        //解析xml
        DeviceApiParam deviceApiParam = new DeviceApiParam();
        if (requestdata != null && requestdata.length() > 0) {
            Element data = null;
            StringReader sr = new StringReader(requestdata);
            InputSource is = new InputSource(sr);
            SAXReader reader = new SAXReader();
            org.dom4j.Document document = reader.read(is);
            //get root Node
            Element root = document.getRootElement();
            if (root.content().size() != 0) {
                deviceApiParam = analysisXmlAuthData(deviceApiParam, root);
                data = root.element("Data");
                if (data != null) {
                    if (data.element("Session") != null) {
                        String session = data.element("Session").getStringValue();
                        if (session != null) {
                            deviceApiParam.setSession(session);
                        }
                    }
                    if (data.element("PeerId") != null) {
                        String peerId = data.element("PeerId").getStringValue();
                        if (peerId != null) {
                            deviceApiParam.setPeerId(peerId);
                        }
                    }
                }
            }
        }
        return deviceApiParam;
    }


    private DeviceApiParam analysisXmlAuthData(DeviceApiParam deviceApiParam, Element root) throws Exception {
        if (root.content().size() != 0) {
            Element appkeyEl = root.element("Appkey");
            Element timestampEl = root.element("Timestamp");
            Element signatureEl = root.element("Signature");
            if (appkeyEl != null) {
                deviceApiParam.setAppkey(appkeyEl.getStringValue());
            }
            if (timestampEl != null) {
                deviceApiParam.setTimestamp(timestampEl.getStringValue());
            }
            if (signatureEl != null) {
                deviceApiParam.setSignature(signatureEl.getStringValue());
            }
            deviceApiParam.setRequestId(MyUtil.getUUID());
        }
        return deviceApiParam;
    }


    private void responseGridMetadata(HttpServletResponse response, Result result, String type) {
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            if (StringUtils.equalsIgnoreCase(type, DeviceApiConstant.XML_PARAM)) {
                Object result1 = result.getResult();
                writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
                writer.write("<Root>");
                writer.write("<ErrorCode>" + result.getErrorCode() + "</ErrorCode>");
                writer.write("<ErrorInfo>" + result.getErrorInfo() + "</ErrorInfo>");
                if (result1 != null) {
                    GridMetadata gridMetadata = (GridMetadata) result1;
                    writer.write("<Data>");
                    writer.write("<Title>" + gridMetadata.getTitle() + "</Title>");
                    writer.write("<Reporter>" + gridMetadata.getReporter() + "</Reporter>");
                    writer.write("<StorySlug>" + gridMetadata.getStorySlug() + "</StorySlug>");
                    writer.write("<StationName>" + gridMetadata.getStationName() + "</StationName>");
                    writer.write("<StationAddress>" + gridMetadata.getStationAddress() + "</StationAddress>");
                    writer.write("<Phone>" + gridMetadata.getPhone() + "</Phone>");
                    writer.write("<Email>" + gridMetadata.getEmail() + "</Email>");
                    writer.write("<Location>" + gridMetadata.getLocation() + "</Location>");
                    writer.write("<Longitude>" + gridMetadata.getLongitude() + "</Longitude>");
                    writer.write("<Latitude>" + gridMetadata.getLatitude() + "</Latitude>");
                    writer.write("<StartTime>" + gridMetadata.getStartTime() + "</StartTime>");
                    writer.write("<ExpireTime>" + gridMetadata.getExpireTime() + "</ExpireTime>");
                    writer.write("<ExtraneousInfo>" + gridMetadata.getExtraneousInfo() + "</ExtraneousInfo>");
                    writer.write("</Data>");
                }
                writer.write("</Root>");
            } else {
                writer.write(JsonUtil.toJsonStr(result));
            }
        } catch (IOException e) {
            log.error(e.toString(), e);
        } finally {
            if (writer!=null){
                writer.flush();
                writer.close();
            }

        }

    }

    private void response(HttpServletResponse response, Result result, String type, String fun) {
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            if (type.equalsIgnoreCase(DeviceApiConstant.XML_PARAM)) {
                writer.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                writer.write("<Root>");
                if (result.getErrorCode().equals("0x0")) {
                    writer.write("<ErrorCode>" + "0" + "</ErrorCode>");
                    writer.write("<ErrorInfo>" + "Success" + "</ErrorInfo>");
                    if ("getDeviceList".equals(fun)) {
                        Result<UserDeviceStructure> result1 = result;
                        writer.write("<Data>");
                        writer.write("<SourceList>");
                        try {
                            for (Device device : result1.getResult().getTlist()) {
                                writer.write("<Device>");
                                writer.write("<Name>" + device.getName() + "</Name>");
                                writer.write("<PeerID>" + device.getPeerId() + "</PeerID>");
                                writer.write("<Type>" + device.getType() + "</Type>");
                                writer.write("<Url>" + device.getUrl() + "</Url>");
                                writer.write("<Remark>" + device.getRemark() + "</Remark>");
                                writer.write("</Device>");
                            }
                        } catch (Exception e) {
                            log.error(e.toString(), e);
                        }
                        writer.write("</SourceList>");
                        writer.write("<DestinationList>");
                        try {
                            for (Device device : result1.getResult().getRlist()) {
                                writer.write("<Device>");
                                writer.write("<Name>" + device.getName() + "</Name>");
                                writer.write("<PeerID>" + device.getPeerId() + "</PeerID>");
                                writer.write("<Type>" + device.getType() + "</Type>");
                                writer.write("<Remark>" + device.getRemark() + "</Remark>");
                                writer.write("</Device>");
                            }
                        } catch (Exception e) {
                            log.error(e.toString(), e);
                        }
                        writer.write("</DestinationList>");
                        writer.write("</Data>");
                    } else if ("getStatus".equals(fun)) {
                        Result<List<VoDevice>> result1 = result;
                        writer.write("<Data>");
                        writer.write("<DeviceList>");
                        try {
                            for (VoDevice device : result1.getResult()) {
                                writer.write("<Device>");
                                writer.write("<PeerId>" + device.getPeerId() + "</PeerId>");
                                if( StringUtils.equals(device.getResultCode(), "0x0") ) {
                                    writer.write("<Status>" + device.getStatus() + "</Status>");
                                    writer.write("<Version>" + device.getVersion() + "</Version>");
                                    writer.write("<LivePeerId>" + device.getLivePeerId() + "</LivePeerId>");
                                }else {
                                    writer.write("<FailedReason>"+device.getResultDesc()+"</FailedReason>");
                                }
                                writer.write("</Device>");
                            }
                        } catch (Exception e) {
                            log.error(e.toString(), e);
                        }
                        writer.write("</DeviceList>");
                        writer.write("</Data>");
                    }
                }else {
                    writer.write("<ErrorCode>" + result.getErrorCode() + "</ErrorCode>");
                    writer.write("<ErrorInfo>" + result.getErrorInfo() + "</ErrorInfo>");
                }
                writer.write("</Root>");
            } else {
                writer.write(JsonUtil.toJsonStr(result));
            }
        } catch (IOException e) {
            log.error(e.toString(), e);
        } finally {
            if (writer!=null){
                writer.flush();
                writer.close();
            }

        }

    }

    private Result<DeviceApiParam> analysisUpdateGridMetadataJson(String requestdata) throws Exception {
        Result<DeviceApiParam> result = new Result<>();
        DeviceApiParam deviceApiParam = new DeviceApiParam();
        deviceApiParam.setType(DeviceApiConstant.JSON_PARAM);
        result.setResult(deviceApiParam);
        GridMetadata gridMetadata = new GridMetadata();
        if (StringUtils.isNotEmpty(requestdata)) {
            String peerId = null;
            String title = null;
            String location = null;
            String longitude = null;
            String latitude = null;
            String reporter = null;
            String expireTime = null;
            String startTime = null;
            String createTime = null;
            String storySlug = null;
            String stationName = null;
            String stationAddress = null;
            String phone = null;
            String email = null;
            String extraneousInfo = null;
           com.alibaba.fastjson.JSONObject requestObject = com.alibaba.fastjson.JSONObject.parseObject(requestdata);
           deviceApiParam.setAppkey(requestObject.getString("Appkey"));
            deviceApiParam.setTimestamp(requestObject.getString("Timestamp"));
            deviceApiParam.setSignature(requestObject.getString("Signature"));
            peerId = requestObject.getString("PeerId");
            gridMetadata.setPeerId(peerId);
            if (requestObject.get("Title") != null) {
                title = requestObject.get("Title").toString();
                gridMetadata.setTitle(title);
            }
            if (requestObject.get("Location") != null || requestObject.get("Longitude") != null
                    || requestObject.get("Latitude") != null) {
                if (requestObject.get("Longitude") == null || requestObject.get("Location") == null
                        || requestObject.get("Latitude") == null) {
                    result.setErrorCode("80050040");
                    result.setErrorInfo("Location information is incomplete");
                    return result;
                }
                location = requestObject.get("Location").toString();
                gridMetadata.setLocation(location);
                longitude = requestObject.get("Longitude").toString();
                gridMetadata.setLongitude(longitude);
                latitude = requestObject.get("Latitude").toString();
                gridMetadata.setLatitude(latitude);
            }
            if (requestObject.get("Reporter") != null) {
                reporter = requestObject.get("Reporter").toString();
                gridMetadata.setReporter(reporter);
            }
            if (requestObject.get("ExpireTime") != null && requestObject.get("StartTime") != null) {
                expireTime = requestObject.get("ExpireTime").toString();
                startTime = requestObject.get("StartTime").toString();
                if(expireTime.equals("")){
                    expireTime = "8888888888888";
                }
                if (Long.parseLong(expireTime) < Long
                        .parseLong(startTime)) {
                    result.setErrorCode("80050041");
                    result.setErrorInfo("Expire time cannot be less than start time");
                    // result = ResultUtil.error(1007, "Expire time
                    // cannot be less than start time");
                    return result;
                }
            }
            if (requestObject.get("StartTime") != null) {
                startTime = requestObject.get("StartTime").toString();
                //String st = MyUtil.dateToStamp(startTime);
//							if (Long.parseLong(startTime) < System.currentTimeMillis()) {
//								result.setErrorCode("80050042");
//								result.setErrorInfo("Start time cannot be less than current time");
//								// result = ResultUtil.error(1008, "Start time
//								// cannot be less than current time");
//								return;
//							}
                gridMetadata.setStartTime(Long.parseLong(startTime));
            }
            if (requestObject.get("CreateTime") != null) {
                createTime = requestObject.get("CreateTime").toString();
                gridMetadata.setCreateTime(Long.parseLong(createTime));
            }

            if (requestObject.get("ExpireTime") != null) {
                expireTime = requestObject.get("ExpireTime").toString();
                if(expireTime.equals("")){
                    expireTime = "8888888888888";
                }
                if (Long.parseLong(expireTime) < System.currentTimeMillis()) {
                    result.setErrorCode("80050045");
                    result.setErrorInfo("Expire time cannot be less than current time");
                    return result;
                }
                gridMetadata.setExpireTime(Long.parseLong(expireTime));
            }

            if (requestObject.get("StorySlug") != null) {
                storySlug = requestObject.get("StorySlug").toString();
                storySlug = storySlug.replaceAll("\\\\n","\n");
                gridMetadata.setStorySlug(storySlug);
            }
            if (requestObject.get("StationName") != null) {
                stationName = requestObject.get("StationName").toString();
                gridMetadata.setStationName(stationName);
            }
            if (requestObject.get("StationAddress") != null) {
                stationAddress = requestObject.get("StationAddress").toString();
                gridMetadata.setStationAddress(stationAddress);
            }
            if (requestObject.get("Phone") != null) {
                phone = requestObject.get("Phone").toString();
                gridMetadata.setPhone(phone);
            }
            if (requestObject.get("Email") != null) {
                email = requestObject.get("Email").toString();
                gridMetadata.setEmail(email);
            }
            if (requestObject.get("ExtraneousInfo") != null) {
                extraneousInfo = requestObject.get("ExtraneousInfo").toString();
                extraneousInfo = extraneousInfo.replaceAll("\\\\n","\n");
                gridMetadata.setExtraneousInfo(extraneousInfo);
            }
        }
        deviceApiParam.setGridMetadata(gridMetadata);
        deviceApiParam.setRequestId(MyUtil.getUUID());
        return result.setResult(deviceApiParam);
    }

    private Result<DeviceApiParam> analysisUpdateGridMetadataXml(String requestdata) throws Exception {
        Result<DeviceApiParam> result = new Result<>();
        DeviceApiParam deviceApiParam = new DeviceApiParam();
        deviceApiParam.setType(DeviceApiConstant.XML_PARAM);
        result.setResult(deviceApiParam);
        GridMetadata gridMetadata = new GridMetadata();
        if (StringUtils.isNotEmpty(requestdata)) {
            String appkey = null;
            String timestamp = null;
            String signature = null;
            String peerId = null;
            String title = null;
            String location = null;
            String longitude = null;
            String latitude = null;
            String reporter = null;
            String expireTime = null;
            String startTime = null;
            String storySlug = null;
            String stationName = null;
            String stationAddress = null;
            String phone = null;
            String email = null;
            String extraneousInfo = null;
            if (requestdata.contains("<Root>") && requestdata.contains("</Root>")) {
                // analysis xml
                Element data = null;
                StringReader sr = new StringReader(requestdata);
                InputSource is = new InputSource(sr);
                SAXReader reader = new SAXReader();
                org.dom4j.Document document = reader.read(is);
                try {
                    // get root Node
                    Element root = document.getRootElement();
                    if (root.content().size() != 0) {
                        Element appkeyEl = root.element("Appkey");
                        Element timestampEl = root.element("Timestamp");
                        Element signatureEl = root.element("Signature");
                        if (appkeyEl != null) {
                            appkey = appkeyEl.getStringValue();
                            deviceApiParam.setAppkey(appkey);
                        }
                        if (timestampEl != null) {
                            timestamp = timestampEl.getStringValue();
                            deviceApiParam.setTimestamp(timestamp);
                        }
                        if (signatureEl != null) {
                            signature = signatureEl.getStringValue();
                            deviceApiParam.setSignature(signature);
                        }
                        data = root.element("Data");
                        if (data.content().size() != 0) {

                            if (data.element("PeerId") != null) {
                                peerId = data.element("PeerId").getStringValue().trim();
                                gridMetadata.setPeerId(peerId);
                            }

                            if (data.element("Title") != null) {
                                title = data.element("Title").getStringValue();
                                gridMetadata.setTitle(title);
                            }
                            if (data.element("Location") != null || data.element("Longitude") != null
                                    || data.element("Latitude") != null) {
                                if (data.element("Longitude") == null || data.element("Location") == null
                                        || data.element("Latitude") == null) {
                                    result.setErrorCode("80050040");
                                    result.setErrorInfo("Location information is incomplete");
                                    // result = ResultUtil.error(1006,
                                    // "Location information is
                                    // incomplete");
                                    return result;
                                }
                                location = data.element("Location").getStringValue();
                                longitude = data.element("Longitude").getStringValue();
                                latitude = data.element("Latitude").getStringValue();
                                gridMetadata.setLocation(location);
                                gridMetadata.setLongitude(longitude);
                                gridMetadata.setLatitude(latitude);
                            }
                            if (data.element("Reporter") != null) {
                                reporter = data.element("Reporter").getStringValue();
                                gridMetadata.setReporter(reporter);
                            }
                            if (data.element("ExpireTime") != null && data.element("StartTime") != null) {
                                expireTime = data.element("ExpireTime").getStringValue().trim();
                                startTime = data.element("StartTime").getStringValue().trim();
                                if (expireTime.equals("")) {
                                    expireTime = "8888888888888";
                                }
                                if (Long.parseLong(expireTime) < Long
                                        .parseLong(startTime)) {
                                    result.setErrorCode("80050041");
                                    result.setErrorInfo("Expire time cannot be less than start time");
                                    // result = ResultUtil.error(1007,
                                    // "Expire time cannot be less than
                                    // start time");
                                    return result;
                                }
                            }
                            if (data.element("StartTime") != null) {
                                startTime = data.element("StartTime").getStringValue();
                                //String st = MyUtil.dateToStamp(startTime);
//									if (Long.parseLong(startTime) < System.currentTimeMillis()) {
//										result.setErrorCode("80050042");
//										result.setErrorInfo("Start time cannot be less than current time");
//										// result = ResultUtil.error(1008,
//										// "Start time cannot be less than
//										// current time");
//										return;
//									}
                                gridMetadata.setStartTime(Long.parseLong(startTime.trim()));
                            }

                            if (data.element("ExpireTime") != null) {
                                expireTime = data.element("ExpireTime").getStringValue();
                                if (expireTime.equals("")) {
                                    expireTime = "8888888888888";
                                }
                                if (Long.parseLong(expireTime.trim()) < System.currentTimeMillis()) {
                                    result.setErrorCode("80050045");
                                    result.setErrorInfo("Expire time cannot be less than current time");
                                    return result;
                                }
                                gridMetadata.setExpireTime(Long.parseLong(expireTime.trim()));
                            }

                            if (data.element("StorySlug") != null) {
                                storySlug = data.element("StorySlug").getStringValue();
                                storySlug = storySlug.replaceAll("\\\\n", "\n");
                                gridMetadata.setStorySlug(storySlug);
                            }
                            if (data.element("StationName") != null) {
                                stationName = data.element("StationName").getStringValue();
                                gridMetadata.setStationName(stationName);
                            }
                            if (data.element("StationAddress") != null) {
                                stationAddress = data.element("StationAddress").getStringValue();
                                gridMetadata.setStationAddress(stationAddress);
                            }
                            if (data.element("Phone") != null) {
                                phone = data.element("Phone").getStringValue();
                                gridMetadata.setPhone(phone);
                            }
                            if (data.element("Email") != null) {
                                email = data.element("Email").getStringValue();
                                gridMetadata.setEmail(email);
                            }
                            if (data.element("ExtraneousInfo") != null) {
                                extraneousInfo = data.element("ExtraneousInfo").getStringValue();
                                extraneousInfo = extraneousInfo.replaceAll("\\\\n", "\n");
                                gridMetadata.setExtraneousInfo(extraneousInfo);
                            }
                        } else {
                            result.setErrorCode("80050002");
                            result.setErrorInfo("Parameter erro");
                            return result;
                        }
                    }
                } catch (Exception e) {
                    log.error("updateGridMetadata API ERROR：" + e.toString(), e);
                    result.setErrorCode("80050033");
                    result.setErrorInfo("Service Exception");
                    return result;
                }
            }
        }
        deviceApiParam.setGridMetadata(gridMetadata);
        deviceApiParam.setRequestId(MyUtil.getUUID());
        return result.setResult(deviceApiParam);
    }

    /**
     *
     * @param request request
     * @param response response
     * @throws   IOException 编译异常
     */
    @PostMapping("/queryPairedTGeoByRid")
    public void queryPairedTGeoByRid(HttpServletRequest request,HttpServletResponse response) throws IOException {
        PrintWriter writer = null;

            writer = response.getWriter();

        String remoteAddr = IpUtils.getClientIpAddr(request);
//        String requestdata = (String)request.getAttribute("requestData");
        String requestdata = null;
        try {
            requestdata = HttpRequestUtil.getRequestDate(request);
        } catch (Exception e) {
            log.error("requestdata Exception:",e);
        }
        DeviceGeoResult<List<DeviceGeoRemoteInfo>> result = new DeviceGeoResult<List<DeviceGeoRemoteInfo>>();
        ResponseStructure<DeviceGeoStructure> resultXml =  new ResponseStructure<DeviceGeoStructure>();

        String jsonOrXml = request.getHeader("AccessKey");
        if(StringUtils.isNotEmpty(jsonOrXml)) {
            //处理Json请求
            try {

                log.info("[Receiver ][QueryPairedTGeoByRid API][Request data:]" + requestdata);
                if (requestdata != null && requestdata.length() > 0) {
                    //解析json
                    boolean checkParamFlag = true;
                    JSONObject requestObject = null;
                    try {
                        requestObject = JSONObject.fromObject(requestdata);
                    } catch (Exception e) {
                        log.info(e.getMessage(), e);
                        checkParamFlag = false;
                    }
                    if (checkParamFlag) {
                        result = deviceGeoApiService.getDeviceGeoInfoListJson(requestObject, remoteAddr);
                    }
                }
            } catch (Exception e) {
                result.setResult(DeviceGeoResponse.EXCEPTION);
            } finally {
                writer.write(JSONObject.fromObject(result).toString());
                writer.flush();
            }
            //处理XML请求
        }else {
            try {

                log.info("[Receiver ][ReportThumbnailDevice API][Request data:]" + requestdata);
                if (requestdata != null && requestdata.length() > 0) {
                    resultXml = deviceGeoApiService.getDeviceGeoInfoListXml(requestdata, remoteAddr);
                }
            } catch (Exception e) {
                resultXml.setResult(DeviceGeoResponse.EXCEPTION);
                log.error("ReportThumbnailDevice APi" + e);
            }finally {
                writer.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                writer.write("<Root>");
                writer.write("<ErrorCode>"+resultXml.getErrorCode()+"</ErrorCode>");
                writer.write("<ErrorInfo>"+resultXml.getErrorInfo()+"</ErrorInfo>");
                writer.write("<Data>");
                if(resultXml.getErrorCode().equals("0")){
                    writer.write("<GeoList>");
                    for(DeviceGeoRemoteInfo deviceGeoRemoteInfo : resultXml.getData().getGeoList()){
                        writer.write("<DeviceGeoRemoteInfo>");
                        writer.write("<PeerID>"+deviceGeoRemoteInfo.getPeerID()+"</PeerID>");
                        writer.write("<Accuracy>"+deviceGeoRemoteInfo.getAccuracy()+"</Accuracy>");
                        writer.write("<Latitude>"+deviceGeoRemoteInfo.getLatitude()+"</Latitude>");
                        writer.write("<Longitude>"+deviceGeoRemoteInfo.getLongitude()+"</Longitude>");
                        writer.write("<Timestamp>"+deviceGeoRemoteInfo.getTimestamp()+"</Timestamp>");
                        writer.write("</DeviceGeoRemoteInfo>");
                    }
                    writer.write("</GeoList>");
                }
                writer.write("</Data>");
                writer.write("</Root>");
                writer.flush();
                writer.close();
            }
        }
    }

    /**
     * 移动端主动修改名字
     * @param request 请求头
     * @param response 返回结果
     */

    @PostMapping(value = "/modifyPackName")
    public void modifyPackName(HttpServletRequest request, HttpServletResponse response) {

        String requestdata = null;
        try {
            requestdata = HttpRequestUtil.getRequestDate(request);
        } catch (Exception e) {
            log.error("[Analysis of the request error][Request data:]" + requestdata);
        }
        log.error("[Anywhere ][modifyPackName][Request data:]" + requestdata);
        //因为该接口绕过了拦截器,还没有做鉴权校验.所以在业务层鉴权
        //为什么这个接口不在拦截器鉴权,因为Anywhere移动端发请求时,将appkey等信息放在http的body里,而拦截器判断的是head里面的信息
        boolean auth = anywhereAuthUtil.anyWhereAuth(request,requestdata);
        PrintWriter writer = null;
        Result errorObj = new Result();
        if (auth) {
            //json参数
            com.alibaba.fastjson.JSONObject requestObject = com.alibaba.fastjson.JSONObject.parseObject(requestdata);
            String peerId = requestObject.getString("packId");
            String name = requestObject.getString("name");
            Result<String> session = userFeignService.getSuperAdminSession();
            Result<String> stringResult = deviceService.updateAnywhereName(peerId, name, session.getResult());

            try {
                writer = response.getWriter();
                if ("0x0".equals(stringResult.getErrorCode())) {
                    errorObj.setErrorCode("0x0");
                    errorObj.setErrorInfo("Success");
                    writer.write(JSONObject.fromObject(errorObj).toString());
                    log.error("modifyPackName Rusult=======" + errorObj);
                } else {
                    errorObj.setErrorCode(stringResult.getErrorCode());
                    errorObj.setErrorCode(stringResult.getErrorInfo());
                    writer.write(JSONObject.fromObject(errorObj).toString());
                    log.error("modifyPackName  error Rusult=======" + errorObj);
                }
            } catch (Exception e) {
                log.error("writer the  result message is error. e : [{}]", e);
            } finally {
                assert writer != null;
                writer.flush();
            }
        } else {
            try {
                writer = response.getWriter();
                errorObj.setErrorCode("0x6");
                errorObj.setErrorInfo("the appkey is not Auth");
                writer.write(JSONObject.fromObject(errorObj).toString());
            } catch (Exception e) {
                log.error("anywhereAuthUtil the  result message is error. e : [{}]", e);
            }
        }
    }

    /**
     * 通知删除slug
     * @param slugInfo 参数
     * @return 是否成功
     * @throws Exception 编译异常
     */
    @PostMapping("/notifyDeleteSlug")
    @ResponseBody
    public Result notifyDeleteSlug(@RequestBody SlugInfo slugInfo) throws Exception{
        return ResultUtil.success(gridMetadataService.notificationDeleteSlug(slugInfo));
    }


    /**
     *
     * @param response 响应
     * @throws Exception 编译异常
     */
    @PostMapping("/getAllPackPeerId")
    @ResponseBody
    public void getAllPackPeerId(HttpServletResponse response) throws Exception{
        List<Object> pst = deviceService.getPST();
        PrintWriter writer = null;
        try {
                writer = response.getWriter();
                writer.write(JSONArray.fromObject(pst).toString());

        } catch (Exception e) {
            log.error("getAllPackPeerId the  result message is error. e : [{}]", e);
        } finally {
            assert writer != null;
            writer.flush();
        }
    }



    /**
     *
     * @param response 响应
     * @throws Exception 编译异常
     */
    @PostMapping("/getAllReceiverPeerId")
    @ResponseBody
    public void getAllReceiverPeerId(HttpServletResponse response) throws Exception{
        List<Object> pst = deviceService.getPSR();
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            writer.write(JSONArray.fromObject(pst).toString());

        } catch (Exception e) {
            log.error("getAllPackPeerId the  result message is error. e : [{}]", e);
        } finally {
            assert writer != null;
            writer.flush();
        }
    }

    /**
     * 给search服务提供api接口,添加EXT到R上
     * @param param param
     * @return Result
     */
    @PostMapping("/addExtToReceiver")
    @ResponseBody
    public Result addExtToReceiver(@RequestBody AddExtToReceiverParam param) {
        return ResultUtil.success(deviceService.addExtToReceiver(param));
    }

    /**
     * 给search服务提供api接口,解除EXt和R的关系   不刪除DB中的
     * @param param param
     * @return Result
     */
    @PostMapping("/delExtToReceiver")
    @ResponseBody
    public Result delExtToReceiver(@RequestBody AddExtToReceiverParam param) {
        ReceiverDeleteExtParam extParam = new ReceiverDeleteExtParam();
        String sourceId = param.getSourceId();
        List<String> list = new ArrayList<>();
        list.add(sourceId);
        extParam.setRid(param.getRid());
        extParam.setPeerIds(list);
        externalReceiverRelationService.receiverDeleteExt(extParam);
        return ResultUtil.success();
    }
}

